﻿#define NOMINMAX  // 防止Windows.h中的min/max宏冲突

#include <iostream>
#include <string>
#include <Windows.h>
#include <unordered_map>
#include <vector>
#include <stdexcept>
#include <limits>
#include <algorithm>
#include <cctype>
#include <sql.h>
#include <sqlext.h>
#include <tuple>
#pragma comment(lib, "odbc32.lib")

// 配置常量
const int MAX_RECORDS_PER_TABLE = 1000000;
const int TABLES_PER_DATABASE = 10;

// 类别到数据库的映射
const std::unordered_map<std::string, std::string> CATEGORY_TO_DB = {
    {"novels", "db_novels"},
    {"science", "db_science"},
    {"history", "db_history"},
    {"fiction", "db_fiction"},
    {"biography", "db_biography"},
    {"mystery", "db_mystery"},
    {"fantasy", "db_fantasy"},
    {"romance", "db_romance"},
    {"thriller", "db_thriller"},
    {"horror", "db_horror"}
};

class DatabaseException : public std::runtime_error {
public:
    DatabaseException(const std::string& msg) : std::runtime_error(msg) {}
};

class DatabaseConnector {
private:
    SQLHENV m_env;
    SQLHDBC m_conn;
    bool m_connected;

    std::string getLastError(SQLSMALLINT handleType, SQLHANDLE handle) {
        SQLCHAR sqlState[6] = { 0 };
        SQLCHAR messageText[256] = { 0 };
        SQLINTEGER nativeError = 0;
        SQLSMALLINT textLength = 0;

        SQLGetDiagRecA(handleType, handle, 1, sqlState, &nativeError,
            messageText, sizeof(messageText), &textLength);

        return std::string((char*)messageText) + " (SQLState: " +
            std::string((char*)sqlState) + ", NativeError: " +
            std::to_string(nativeError) + ")";
    }

public:
    DatabaseConnector() : m_env(nullptr), m_conn(nullptr), m_connected(false) {
        SQLRETURN ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_env);
        if (!SQL_SUCCEEDED(ret)) {
            throw DatabaseException("分配环境句柄失败");
        }

        ret = SQLSetEnvAttr(m_env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
        if (!SQL_SUCCEEDED(ret)) {
            SQLFreeHandle(SQL_HANDLE_ENV, m_env);
            throw DatabaseException("设置ODBC版本失败");
        }

        ret = SQLAllocHandle(SQL_HANDLE_DBC, m_env, &m_conn);
        if (!SQL_SUCCEEDED(ret)) {
            SQLFreeHandle(SQL_HANDLE_ENV, m_env);
            throw DatabaseException("分配连接句柄失败");
        }
    }

    ~DatabaseConnector() {
        disconnect();
        if (m_conn) SQLFreeHandle(SQL_HANDLE_DBC, m_conn);
        if (m_env) SQLFreeHandle(SQL_HANDLE_ENV, m_env);
    }

    void connect(const std::string& server) {
        if (m_connected) return;

        std::string connStr = "DRIVER={ODBC Driver 17 for SQL Server};SERVER=" + server +
            ";DATABASE=master;Trusted_Connection=Yes;";

        SQLCHAR outConnStr[1024] = { 0 };
        SQLSMALLINT outConnStrLen = 0;
        SQLRETURN ret = SQLDriverConnectA(m_conn, nullptr,
            (SQLCHAR*)connStr.c_str(), SQL_NTS,
            outConnStr, sizeof(outConnStr),
            &outConnStrLen, SQL_DRIVER_NOPROMPT);

        if (!SQL_SUCCEEDED(ret)) {
            std::string errMsg = "数据库连接失败: " + getLastError(SQL_HANDLE_DBC, m_conn);
            throw DatabaseException(errMsg);
        }
        m_connected = true;
    }

    void disconnect() {
        if (m_connected) {
            SQLDisconnect(m_conn);
            m_connected = false;
        }
    }

    void execute(const std::string& dbName, const std::string& sql) {
        SQLHSTMT stmt = nullptr;

        try {
            if (!SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_STMT, m_conn, &stmt))) {
                throw DatabaseException("分配语句句柄失败");
            }

            std::string useDb = "USE " + dbName + ";";
            if (!SQL_SUCCEEDED(SQLExecDirectA(stmt, (SQLCHAR*)useDb.c_str(), SQL_NTS))) {
                throw DatabaseException("切换数据库失败: " + getLastError(SQL_HANDLE_STMT, stmt));
            }

            if (!SQL_SUCCEEDED(SQLExecDirectA(stmt, (SQLCHAR*)sql.c_str(), SQL_NTS))) {
                throw DatabaseException("执行SQL失败: " + getLastError(SQL_HANDLE_STMT, stmt));
            }
        }
        catch (...) {
            if (stmt) SQLFreeHandle(SQL_HANDLE_STMT, stmt);
            throw;
        }

        if (stmt) SQLFreeHandle(SQL_HANDLE_STMT, stmt);
    }

    std::vector<std::vector<std::string>> query(const std::string& dbName, const std::string& sql) {
        SQLHSTMT stmt = nullptr;
        std::vector<std::vector<std::string>> results;

        try {
            if (!SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_STMT, m_conn, &stmt))) {
                throw DatabaseException("分配语句句柄失败");
            }

            std::string useDb = "USE " + dbName + ";";
            if (!SQL_SUCCEEDED(SQLExecDirectA(stmt, (SQLCHAR*)useDb.c_str(), SQL_NTS))) {
                throw DatabaseException("切换数据库失败: " + getLastError(SQL_HANDLE_STMT, stmt));
            }

            if (!SQL_SUCCEEDED(SQLExecDirectA(stmt, (SQLCHAR*)sql.c_str(), SQL_NTS))) {
                throw DatabaseException("执行查询失败: " + getLastError(SQL_HANDLE_STMT, stmt));
            }

            SQLSMALLINT colCount = 0;
            SQLNumResultCols(stmt, &colCount);
            if (colCount <= 0) {
                return results;
            }

            std::vector<std::string> colNames;
            for (SQLSMALLINT i = 1; i <= colCount; ++i) {
                SQLCHAR colName[256] = { 0 };
                SQLSMALLINT nameLen = 0;
                SQLDescribeColA(stmt, i, colName, sizeof(colName), &nameLen,
                    nullptr, nullptr, nullptr, nullptr);
                colNames.push_back(std::string((char*)colName));
            }
            results.push_back(colNames);

            SQLCHAR value[256] = { 0 };
            SQLLEN len = 0;

            while (SQLFetch(stmt) == SQL_SUCCESS) {
                std::vector<std::string> row;

                for (SQLSMALLINT i = 1; i <= colCount; ++i) {
                    if (SQLGetData(stmt, i, SQL_C_CHAR, value, sizeof(value), &len) == SQL_SUCCESS) {
                        row.push_back(len == SQL_NULL_DATA ? "NULL" : std::string((char*)value));
                        memset(value, 0, sizeof(value));
                    }
                    else {
                        row.push_back("ERROR");
                    }
                }

                results.push_back(row);
            }
        }
        catch (...) {
            if (stmt) SQLFreeHandle(SQL_HANDLE_STMT, stmt);
            throw;
        }

        if (stmt) SQLFreeHandle(SQL_HANDLE_STMT, stmt);
        return results;
    }
};

class BookManager {
private:
    DatabaseConnector& m_db;

    std::string getDatabaseName(const std::string& category) const {
        auto it = CATEGORY_TO_DB.find(category);
        if (it == CATEGORY_TO_DB.end()) {
            throw std::runtime_error("未知的图书类别: " + category);
        }
        return it->second;
    }

    std::string getTableName(int bookId) const {
        int tableNum = ((bookId - 1) / MAX_RECORDS_PER_TABLE) % TABLES_PER_DATABASE + 1;
        return "books_" + std::to_string(tableNum);
    }

    std::string escapeSqlString(const std::string& input) {
        std::string output;
        for (char c : input) {
            if (c == '\'') {
                output += "''";
            }
            else {
                output += c;
            }
        }
        return output;
    }

    void clearInputBuffer() {
        std::cin.clear();
        std::cin.ignore((std::numeric_limits<std::streamsize>::max)(), '\n');
    }

    void displayCategories() {
        std::cout << "\n支持的图书类别:\n";
        for (const auto& pair : CATEGORY_TO_DB) {
            std::cout << " - " << pair.first << "\n";
        }
        std::cout << std::endl;
    }

    std::string toLower(const std::string& str) {
        std::string lowerStr = str;
        std::transform(lowerStr.begin(), lowerStr.end(), lowerStr.begin(),
            [](unsigned char c) { return std::tolower(c); });
        return lowerStr;
    }

    void displayBookDetails(const std::vector<std::vector<std::string>>& results) {
        if (results.size() <= 1) return;

        std::cout << "\n图书详细信息:\n";
        for (size_t i = 0; i < results[0].size(); ++i) {
            std::cout << results[0][i] << ": " << results[1][i] << "\n";
        }
    }

public:
    BookManager(DatabaseConnector& db) : m_db(db) {}

    // 添加图书
    void addBookInteractive() {
        std::cout << "\n=== 添加新图书 ===\n";

        int bookId;
        std::string title, author, category, publishDate, description;
        double price = 0.0;

        std::cout << "请输入图书ID: ";
        while (!(std::cin >> bookId)) {
            std::cout << "无效的ID，请重新输入: ";
            clearInputBuffer();
        }
        clearInputBuffer();

        std::cout << "请输入书名: ";
        std::getline(std::cin, title);

        std::cout << "请输入作者: ";
        std::getline(std::cin, author);

        displayCategories();
        std::cout << "请输入图书类别: ";
        std::getline(std::cin, category);

        while (CATEGORY_TO_DB.find(category) == CATEGORY_TO_DB.end()) {
            std::cout << "无效的类别，请从上述列表中选择: ";
            std::getline(std::cin, category);
        }

        std::cout << "请输入出版日期(YYYY-MM-DD，可选): ";
        std::getline(std::cin, publishDate);

        std::cout << "请输入价格(可选): ";
        std::string priceStr;
        std::getline(std::cin, priceStr);
        if (!priceStr.empty()) {
            try {
                price = std::stod(priceStr);
            }
            catch (...) {
                std::cout << "无效的价格，将使用默认值0.0\n";
                price = 0.0;
            }
        }

        std::cout << "请输入描述(可选): ";
        std::getline(std::cin, description);

        std::cout << "\n即将添加以下图书信息:\n";
        std::cout << "ID: " << bookId << "\n";
        std::cout << "书名: " << title << "\n";
        std::cout << "作者: " << author << "\n";
        std::cout << "类别: " << category << "\n";
        std::cout << "出版日期: " << (publishDate.empty() ? "未指定" : publishDate) << "\n";
        std::cout << "价格: " << price << "\n";
        std::cout << "描述: " << (description.empty() ? "未指定" : description) << "\n";

        std::cout << "\n确认添加吗？(Y/N): ";
        char confirm;
        std::cin >> confirm;
        clearInputBuffer();

        if (tolower(confirm) == 'y') {
            try {
                addBook(bookId, title, author, category, publishDate, price, description);
                std::cout << "图书添加成功！\n";
            }
            catch (const std::exception& e) {
                std::cerr << "添加图书失败: " << e.what() << std::endl;
            }
        }
        else {
            std::cout << "已取消添加操作\n";
        }
    }

    // 批量添加图书
    void batchAddBooksInteractive() {
        std::cout << "\n=== 批量添加图书 ===\n";

        std::vector<std::tuple<int, std::string, std::string, std::string, std::string, double, std::string>> books;

        while (true) {
            int bookId;
            std::string title, author, category, publishDate, description;
            double price = 0.0;

            std::cout << "\n输入图书信息(输入ID为0结束):\n";

            std::cout << "图书ID: ";
            while (!(std::cin >> bookId)) {
                std::cout << "无效的ID，请重新输入: ";
                clearInputBuffer();
            }
            clearInputBuffer();

            if (bookId == 0) break;

            std::cout << "书名: ";
            std::getline(std::cin, title);

            std::cout << "作者: ";
            std::getline(std::cin, author);

            displayCategories();
            std::cout << "类别: ";
            std::getline(std::cin, category);

            while (CATEGORY_TO_DB.find(category) == CATEGORY_TO_DB.end()) {
                std::cout << "无效的类别，请从上述列表中选择: ";
                std::getline(std::cin, category);
            }

            std::cout << "出版日期(YYYY-MM-DD，可选): ";
            std::getline(std::cin, publishDate);

            std::cout << "价格(可选): ";
            std::string priceStr;
            std::getline(std::cin, priceStr);
            if (!priceStr.empty()) {
                try {
                    price = std::stod(priceStr);
                }
                catch (...) {
                    std::cout << "无效的价格，将使用默认值0.0\n";
                    price = 0.0;
                }
            }

            std::cout << "描述(可选): ";
            std::getline(std::cin, description);

            books.emplace_back(bookId, title, author, category, publishDate, price, description);

            std::cout << "已添加图书 #" << bookId << " 到批量列表 (当前共 " << books.size() << " 本)\n";
        }

        if (books.empty()) {
            std::cout << "没有图书需要添加\n";
            return;
        }

        std::cout << "\n即将批量添加以下 " << books.size() << " 本图书:\n";
        for (const auto& book : books) {
            std::cout << "ID: " << std::get<0>(book) << ", 书名: " << std::get<1>(book)
                << ", 作者: " << std::get<2>(book) << "\n";
        }

        std::cout << "\n确认批量添加吗？(Y/N): ";
        char confirm;
        std::cin >> confirm;
        clearInputBuffer();

        if (tolower(confirm) == 'y') {
            try {
                batchAddBooks(books);
                std::cout << "成功批量添加 " << books.size() << " 本图书！\n";
            }
            catch (const std::exception& e) {
                std::cerr << "批量添加失败: " << e.what() << std::endl;
            }
        }
        else {
            std::cout << "已取消批量添加操作\n";
        }
    }

    // 查询图书
    void queryBookInteractive() {
        std::cout << "\n=== 查询图书 ===\n";

        int bookId;
        std::string category;

        std::cout << "请输入要查询的图书ID: ";
        while (!(std::cin >> bookId)) {
            std::cout << "无效的ID，请重新输入: ";
            clearInputBuffer();
        }
        clearInputBuffer();

        displayCategories();
        std::cout << "请输入图书类别: ";
        std::getline(std::cin, category);

        while (CATEGORY_TO_DB.find(category) == CATEGORY_TO_DB.end()) {
            std::cout << "无效的类别，请从上述列表中选择: ";
            std::getline(std::cin, category);
        }

        try {
            getBook(bookId, category);
        }
        catch (const std::exception& e) {
            std::cerr << "查询图书失败: " << e.what() << std::endl;
        }
    }

    // 更新图书
    void updateBookInteractive() {
        std::cout << "\n=== 更新图书信息 ===\n";

        int bookId;
        std::string category;

        std::cout << "请输入要更新的图书ID: ";
        while (!(std::cin >> bookId)) {
            std::cout << "无效的ID，请重新输入: ";
            clearInputBuffer();
        }
        clearInputBuffer();

        displayCategories();
        std::cout << "请输入图书类别: ";
        std::getline(std::cin, category);

        while (CATEGORY_TO_DB.find(category) == CATEGORY_TO_DB.end()) {
            std::cout << "无效的类别，请从上述列表中选择: ";
            std::getline(std::cin, category);
        }

        try {
            // 先查询图书是否存在
            auto results = getBook(bookId, category, false);
            if (results.size() <= 1) {
                std::cout << "未找到指定图书，无法更新\n";
                return;
            }

            displayBookDetails(results);

            // 获取更新字段
            std::string title, author, newCategory, publishDate, description;
            double price = 0.0;

            std::cout << "\n请输入新的书名(直接回车保持原值): ";
            std::getline(std::cin, title);

            std::cout << "请输入新的作者(直接回车保持原值): ";
            std::getline(std::cin, author);

            std::cout << "请输入新的类别(直接回车保持原值): ";
            std::getline(std::cin, newCategory);
            if (!newCategory.empty() && CATEGORY_TO_DB.find(newCategory) == CATEGORY_TO_DB.end()) {
                std::cout << "无效的类别，将保持原值\n";
                newCategory.clear();
            }

            std::cout << "请输入新的出版日期(YYYY-MM-DD，直接回车保持原值): ";
            std::getline(std::cin, publishDate);

            std::cout << "请输入新的价格(直接回车保持原值): ";
            std::string priceStr;
            std::getline(std::cin, priceStr);
            if (!priceStr.empty()) {
                try {
                    price = std::stod(priceStr);
                }
                catch (...) {
                    std::cout << "无效的价格，将保持原值\n";
                    priceStr.clear();
                }
            }

            std::cout << "请输入新的描述(直接回车保持原值): ";
            std::getline(std::cin, description);

            // 确认更新
            std::cout << "\n确认更新吗？(Y/N): ";
            char confirm;
            std::cin >> confirm;
            clearInputBuffer();

            if (tolower(confirm) == 'y') {
                updateBook(bookId, category, newCategory.empty() ? category : newCategory,
                    title, author, publishDate, priceStr.empty() ? -1 : price, description);
                std::cout << "图书信息更新成功！\n";
            }
            else {
                std::cout << "已取消更新操作\n";
            }
        }
        catch (const std::exception& e) {
            std::cerr << "更新图书失败: " << e.what() << std::endl;
        }
    }

    // 删除图书
    void deleteBookInteractive() {
        std::cout << "\n=== 删除图书 ===\n";

        int bookId;
        std::string category;

        std::cout << "请输入要删除的图书ID: ";
        while (!(std::cin >> bookId)) {
            std::cout << "无效的ID，请重新输入: ";
            clearInputBuffer();
        }
        clearInputBuffer();

        displayCategories();
        std::cout << "请输入图书类别: ";
        std::getline(std::cin, category);

        while (CATEGORY_TO_DB.find(category) == CATEGORY_TO_DB.end()) {
            std::cout << "无效的类别，请从上述列表中选择: ";
            std::getline(std::cin, category);
        }

        try {
            // 先查询图书是否存在
            auto results = getBook(bookId, category, false);
            if (results.size() <= 1) {
                std::cout << "未找到指定图书，无法删除\n";
                return;
            }

            displayBookDetails(results);

            std::cout << "\n确认删除吗？此操作不可恢复！(Y/N): ";
            char confirm;
            std::cin >> confirm;
            clearInputBuffer();

            if (tolower(confirm) == 'y') {
                deleteBook(bookId, category);
                std::cout << "图书删除成功！\n";
            }
            else {
                std::cout << "已取消删除操作\n";
            }
        }
        catch (const std::exception& e) {
            std::cerr << "删除图书失败: " << e.what() << std::endl;
        }
    }

    // 显示主菜单
    void showMenu() {
        while (true) {
            std::cout << "\n=== 图书管理系统 ===\n";
            std::cout << "1. 添加图书\n";
            std::cout << "2. 批量添加图书\n";
            std::cout << "3. 查询图书\n";
            std::cout << "4. 更新图书\n";
            std::cout << "5. 删除图书\n";
            std::cout << "6. 退出系统\n";
            std::cout << "请选择操作(1-6): ";

            int choice;
            if (!(std::cin >> choice)) {
                clearInputBuffer();
                std::cout << "无效的输入，请重新选择\n";
                continue;
            }
            clearInputBuffer();

            try {
                switch (choice) {
                case 1:
                    addBookInteractive();
                    break;
                case 2:
                    batchAddBooksInteractive();
                    break;
                case 3:
                    queryBookInteractive();
                    break;
                case 4:
                    updateBookInteractive();
                    break;
                case 5:
                    deleteBookInteractive();
                    break;
                case 6:
                    std::cout << "感谢使用，再见！\n";
                    return;
                default:
                    std::cout << "无效的选择，请重新输入\n";
                }
            }
            catch (const std::exception& e) {
                std::cerr << "操作失败: " << e.what() << std::endl;
            }
        }
    }

private:
    // 实际添加图书的方法
    void addBook(int bookId, const std::string& title, const std::string& author,
        const std::string& category, const std::string& publishDate,
        double price, const std::string& description) {
        std::string dbName = getDatabaseName(category);
        std::string tableName = getTableName(bookId);

        std::string sql = "INSERT INTO " + tableName +
            " (book_id, title, author, category, publish_date, price, description) " +
            "VALUES (" + std::to_string(bookId) + ", ";

        sql += "'" + escapeSqlString(title) + "', ";
        sql += "'" + escapeSqlString(author) + "', ";
        sql += "'" + escapeSqlString(category) + "', ";

        if (publishDate.empty()) {
            sql += "NULL, ";
        }
        else {
            sql += "'" + escapeSqlString(publishDate) + "', ";
        }

        sql += std::to_string(price) + ", ";

        if (description.empty()) {
            sql += "NULL";
        }
        else {
            sql += "'" + escapeSqlString(description) + "'";
        }

        sql += ")";

        m_db.execute(dbName, sql);
    }

    // 实际批量添加图书的方法
    void batchAddBooks(const std::vector<std::tuple<int, std::string, std::string, std::string,
        std::string, double, std::string>>&books) {
        // 按数据库和表分组，减少连接切换
        std::unordered_map<std::string,
            std::unordered_map<std::string,
            std::vector<std::tuple<int, std::string, std::string,
            std::string, double, std::string>>>> groupedBooks;

        // 分组图书
        for (const auto& book : books) {
            int bookId = std::get<0>(book);
            const std::string& category = std::get<3>(book);
            std::string dbName = getDatabaseName(category);
            std::string tableName = getTableName(bookId);

            groupedBooks[dbName][tableName].emplace_back(
                bookId, std::get<1>(book), std::get<2>(book),
                std::get<4>(book), std::get<5>(book), std::get<6>(book)
            );
        }

        // 为每个数据库和表执行批量插入
        for (const auto& dbPair : groupedBooks) {
            const std::string& dbName = dbPair.first;

            for (const auto& tablePair : dbPair.second) {
                const std::string& tableName = tablePair.first;
                const auto& tableBooks = tablePair.second;

                // 构建批量插入SQL
                std::string sql = "INSERT INTO " + tableName +
                    " (book_id, title, author, category, publish_date, price, description) VALUES ";

                bool first = true;
                for (const auto& book : tableBooks) {
                    if (!first) sql += ", ";
                    first = false;

                    sql += "(" + std::to_string(std::get<0>(book)) + ", ";
                    sql += "'" + escapeSqlString(std::get<1>(book)) + "', ";
                    sql += "'" + escapeSqlString(std::get<2>(book)) + "', ";
                    sql += "'" + escapeSqlString(dbPair.first.substr(3)) + "', "; // 从db_novels提取novels

                    if (std::get<3>(book).empty()) {
                        sql += "NULL, ";
                    }
                    else {
                        sql += "'" + escapeSqlString(std::get<3>(book)) + "', ";
                    }

                    sql += std::to_string(std::get<4>(book)) + ", ";

                    if (std::get<5>(book).empty()) {
                        sql += "NULL";
                    }
                    else {
                        sql += "'" + escapeSqlString(std::get<5>(book)) + "'";
                    }

                    sql += ")";
                }

                // 执行批量插入
                m_db.execute(dbName, sql);
            }
        }
    }

    // 实际查询图书的方法
    std::vector<std::vector<std::string>> getBook(int bookId, const std::string& category, bool display = true) {
        std::string dbName = getDatabaseName(category);
        std::string tableName = getTableName(bookId);

        std::string sql = "SELECT * FROM " + tableName +
            " WHERE book_id = " + std::to_string(bookId);

        auto results = m_db.query(dbName, sql);

        if (display) {
            if (results.size() <= 1) {
                std::cout << "未找到图书 #" << bookId << " 在 "
                    << dbName << "." << tableName << std::endl;
            }
            else {
                std::cout << "\n图书详细信息 (" << dbName << "." << tableName << "):\n";
                for (size_t i = 0; i < results[0].size(); ++i) {
                    std::cout << results[0][i] << ": " << results[1][i] << "\n";
                }
            }
        }

        return results;
    }

    // 实际更新图书的方法
    void updateBook(int bookId, const std::string& oldCategory, const std::string& newCategory,
        const std::string& title, const std::string& author,
        const std::string& publishDate, double price, const std::string& description) {
        std::string oldDbName = getDatabaseName(oldCategory);
        std::string newDbName = getDatabaseName(newCategory);
        std::string tableName = getTableName(bookId);

        // 构建更新SQL
        std::string sql = "UPDATE " + tableName + " SET ";
        bool needComma = false;

        if (!title.empty()) {
            sql += "title = '" + escapeSqlString(title) + "'";
            needComma = true;
        }

        if (!author.empty()) {
            if (needComma) sql += ", ";
            sql += "author = '" + escapeSqlString(author) + "'";
            needComma = true;
        }

        if (!newCategory.empty() && newCategory != oldCategory) {
            if (needComma) sql += ", ";
            sql += "category = '" + escapeSqlString(newCategory) + "'";
            needComma = true;
        }

        if (!publishDate.empty()) {
            if (needComma) sql += ", ";
            sql += "publish_date = '" + escapeSqlString(publishDate) + "'";
            needComma = true;
        }

        if (price >= 0) {
            if (needComma) sql += ", ";
            sql += "price = " + std::to_string(price);
            needComma = true;
        }

        if (!description.empty()) {
            if (needComma) sql += ", ";
            sql += "description = '" + escapeSqlString(description) + "'";
        }

        sql += " WHERE book_id = " + std::to_string(bookId);

        // 如果类别改变了，需要先删除再插入到新库
        if (!newCategory.empty() && newCategory != oldCategory) {
            // 先获取原数据
            auto oldData = getBook(bookId, oldCategory, false);
            if (oldData.size() <= 1) {
                throw std::runtime_error("无法找到原图书数据");
            }

            // 删除原数据
            deleteBook(bookId, oldCategory, false);

            // 插入新数据
            std::string newTableName = getTableName(bookId);
            std::string insertSql = "INSERT INTO " + newTableName +
                " (book_id, title, author, category, publish_date, price, description) " +
                "VALUES (" + std::to_string(bookId) + ", ";

            insertSql += "'" + escapeSqlString(title.empty() ? oldData[1][1] : title) + "', ";
            insertSql += "'" + escapeSqlString(author.empty() ? oldData[1][2] : author) + "', ";
            insertSql += "'" + escapeSqlString(newCategory) + "', ";
            insertSql += (publishDate.empty() ?
                (oldData[1][4] == "NULL" ? "NULL, " : "'" + escapeSqlString(oldData[1][4]) + "', ") :
                "'" + escapeSqlString(publishDate) + "', ");
            insertSql += (price < 0 ?
                (oldData[1][5] == "NULL" ? "0, " : oldData[1][5] + ", ") :
                std::to_string(price) + ", ");
            insertSql += (description.empty() ?
                (oldData[1][6] == "NULL" ? "NULL" : "'" + escapeSqlString(oldData[1][6]) + "'") :
                "'" + escapeSqlString(description) + "'");

            insertSql += ")";

            m_db.execute(newDbName, insertSql);
        }
        else {
            // 直接更新
            m_db.execute(oldDbName, sql);
        }
    }

    // 实际删除图书的方法
    void deleteBook(int bookId, const std::string& category, bool checkExistence = true) {
        std::string dbName = getDatabaseName(category);
        std::string tableName = getTableName(bookId);

        if (checkExistence) {
            auto results = getBook(bookId, category, false);
            if (results.size() <= 1) {
                throw std::runtime_error("图书不存在");
            }
        }

        std::string sql = "DELETE FROM " + tableName +
            " WHERE book_id = " + std::to_string(bookId);

        m_db.execute(dbName, sql);
    }
};

int main() {
    try {
        std::string server = "localhost";  // 或你的服务器名称

        DatabaseConnector dbConnector;
        std::cout << "正在连接到SQL Server..." << std::endl;
        dbConnector.connect(server);
        std::cout << "成功连接到SQL Server" << std::endl;

        BookManager bookManager(dbConnector);
        bookManager.showMenu();

        dbConnector.disconnect();
    }
    catch (const std::exception& e) {
        std::cerr << "程序发生错误: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}